代理模式 Proxy Pattern
为另一个对象提供替身或者占位符以控制这个对象的访问。
通常代理类内含有一个被代理类的引用。
类图
代理分类
远程代理
通过 RMI 和 JNDI 进行远程方法调用,在不同 JVM 中进行交互。
虚拟代理
通常利用代理对象来创建和销毁占用较多资源的被代理对象。用来延迟大资源对象的创建。
动态代理 Dynamic Proxy
java.lang.reflect.Proxy
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
InvocationHandler
是代理实例的调用处理程序实现的接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
动态Proxy是这样的一种类:
它是在运行生成的类,在生成时你必须提供一组Interface给它,然后该class就宣称它实现了这些interface。你可以把该class的实例当作这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
在使用动态代理类时,我们必须实现InvocationHandler
接口
步骤:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| interface Subject { void action(); }
class RealSubject implements Subject { public void action() { System.out.println( "我是被代理类,记得要执行我!" ); } }
class MyInvocationHandler implements InvocationHandler { Object obj;
public Object blind(Object obj) { this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object returnVal = method.invoke(obj, args); return returnVal; } }
public class TestProxy { public static void main(String[] args) { RealSubject real = new RealSubject(); MyInvocationHandler handler = new MyInvocationHandler(); Object obj = handler.blind(real); Subject sub = (Subject)obj; sub.action(); } }
|